﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using Controllers;
using Interfaces;
using Microsoft.Win32;

namespace Hesehus
{
    public partial class Backend
    {
        #region Fields

        readonly StartUp _window;
        readonly Controller _controller;
        readonly string[] _materials = new[] { "Silke", "Bomuld", "Uld", "Læder", "Polyester", "Nylon" };

        #endregion

        #region Creation

        public Backend(StartUp window)
        {
            InitializeComponent();

            _window = window;
            _controller = new Controller();

            //Tilstandsstyring
            OnLoadingWindow();

            //Sætter indlæs data til default tab.
            tabGetData.Focus();

            // gør koden tilgængelig i xaml filen (databinding bl.a)
            DataContext = this;

            List<IBrand> brands = _controller.GetBrands();
            cmbBrand.ItemsSource = brands;

            List<ICategory> categories = _controller.GetCategories();
            cmbCategory.ItemsSource = categories;

            //Tilføjer materialer til cmbmMterial
            cmbMaterial.ItemsSource = _materials;
        }

        #endregion

        #region StateManagement

        //Når window load kør tilstandstyring
        private void OnLoadingWindow()
        {
            cmbBrand.IsEnabled = true;
            cmbBrand.SelectedIndex = -1;
            cmbCategory.IsEnabled = false;
            cmbCategory.SelectedIndex = -1;
            cmbGenericItem.IsEnabled = false;
            cmbGenericItem.SelectedIndex = -1;
            cmbItem.IsEnabled = false;
            cmbItem.SelectedIndex = -1;
            cmbMaterial.IsEnabled = false;
            cmbMaterial.SelectedIndex = -1;
            txtDiscountPrice.IsEnabled = false;
            txtDiscountPrice.Clear();
            txtDisplayName.IsEnabled = false;
            txtDisplayName.Clear();
            txtDescription.IsEnabled = false;
            txtDescription.Clear();
            txtOriginlPrice.Clear();
            txtQuantity.Clear();
            btnUploadPicture.IsEnabled = false;
            btnClear.IsEnabled = false;
            btnSave.IsEnabled = false;
            mainImage.Source = null;

        }

        private void BrandSelected()
        {
            cmbCategory.IsEnabled = true;
            cmbGenericItem.IsEnabled = false;
            cmbGenericItem.SelectedIndex = -1;
            cmbItem.IsEnabled = false;
            cmbItem.SelectedIndex = -1;
            cmbMaterial.IsEnabled = false;
            cmbMaterial.SelectedIndex = -1;
            txtDiscountPrice.IsEnabled = false;
            txtDiscountPrice.Clear();
            txtDisplayName.IsEnabled = false;
            txtDisplayName.Clear();
            txtDescription.IsEnabled = false;
            txtDescription.Clear();
            txtOriginlPrice.Clear();
            txtQuantity.Clear();
            btnUploadPicture.IsEnabled = false;
            btnClear.IsEnabled = true;
            btnSave.IsEnabled = false;
            mainImage.Source = null;
        }

        private void CategorySelected()
        {
            cmbGenericItem.IsEnabled = true;
        }

        private void GenericItemSelected()
        {
            cmbItem.IsEnabled = true;
            cmbMaterial.IsEnabled = true;
            txtDiscountPrice.IsEnabled = true;
            txtDisplayName.IsEnabled = true;
            txtDescription.IsEnabled = true;
            btnUploadPicture.IsEnabled = false;
            mainImage.Source = null;
            if (cmbMaterial.SelectedIndex == -1)
                btnSave.IsEnabled = false;
        }

        private void ItemSelected()
        {
            btnUploadPicture.IsEnabled = true;
        }

        private void MaterialSelected()
        {
            btnSave.IsEnabled = true;
        }


        #endregion

        #region Event Handlers

        //Knap til indlæsning af .XML fil
        private void loadXml_Click(object sender, RoutedEventArgs e)
        {
            var dialog = new OpenFileDialog {Filter = "XML files (*.xml)|*.xml"};

            bool? dialogResult = dialog.ShowDialog();

            // brugeren valgte en xml fil
            if (dialogResult.Value)
                // hvis import af xml var successfuld
                if (_controller.SendInput(dialog.FileName))
                    MessageBox.Show("XML Data importeret!", "Success", MessageBoxButton.OK, MessageBoxImage.Information);
                else
                    MessageBox.Show(
                        "Der var en fejl ved importering af XML data, er du sikker på du har den rigtige struktur?", "Fejl", 
                        MessageBoxButton.OK, MessageBoxImage.Error);
        }

        private void UploadPicture(object sender, RoutedEventArgs e)
        {
            var dialog = new OpenFileDialog {Filter = "Image Files(*.PNG;*.JPG)|*.PNG;*.JPG"};
            
            bool? dialogResult = dialog.ShowDialog();

            // brugeren valgte et billede
            if (dialogResult.Value)
            {
                var genericItem = ((IGenericItem)cmbGenericItem.SelectedItem);
                var item = ((IItem)cmbItem.SelectedItem);

                // får en besked mht. billede upload status
                bool result = _controller.SendImageInput(dialog.FileName, genericItem.Id, item.Id);
                if (result)
                {
                    var itemImage = _controller.GetItemImage(genericItem.Id, item.Id);
                    if (itemImage != null)
                    {
                        mainImage.Source = itemImage;
                    }
                }
                else MessageBox.Show("Der var en fejl ved upload af billede.");
            }
        }

        private void cmb_ItemSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            // Der er valgt et item
            if (cmbItem.SelectedIndex != -1)
            {
                // tag selected combobox items, cast til interfaces
                var item = (IItem)cmbItem.SelectedItem;
                var genericItem = (IGenericItem)cmbGenericItem.SelectedItem;

                txtQuantity.Text = item.Quantity.ToString();

                // hent tilhørende billede til det valgte item
                var itemImage = _controller.GetItemImage(genericItem.Id, item.Id);

                // hvis der blev fundet et billede
                if (itemImage != null)
                {
                    mainImage.Source = itemImage;
                }
                // der blev ikke fundet et billede, brug standard billede
                else
                {
                    var uriSource = new Uri(@"Images\missing-image.jpg", UriKind.Relative);
                    mainImage.Source = new BitmapImage(uriSource);
                }
                // kald tilstandsstyring
                ItemSelected();
            }
        }

        private void cmb_GenericItemSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            // der er valgt et item
            if (cmbGenericItem.SelectedIndex != -1)
            {
                // selected combobox item, cast til interface
                var genericItem = (IGenericItem)cmbGenericItem.SelectedItem;

                // opdater item collection
                _controller.PopulateItemCollection(genericItem);

                // opdater varens pris, til valgte generic item
                txtOriginlPrice.Text = genericItem.Price.ToString();

                // ryd items fra combobox, da vi skal indlæse nye data
                cmbItem.Items.Clear();

                // henter liste med items fra objekt
                List<IItem> items = genericItem.GetItems();

                // tilføj alle IItems til combobox
                items.ForEach(element => cmbItem.Items.Add(element));

                // vælger IItemDescription objektet på det valgte item og henter værdierne ind i de passende felter.
                IItemDescription selectedGenericItem = _controller.SelectItemDescription(genericItem.Id);
                cmbMaterial.SelectedValue = selectedGenericItem.Material;
                txtDiscountPrice.Text = selectedGenericItem.DiscountPrice.ToString();
                txtDisplayName.Text = selectedGenericItem.DisplayName;
                txtDescription.Text = selectedGenericItem.Description;

                // kalder tilstandsstyringen
                GenericItemSelected();
            }
        }

        private void cmb_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (cmbBrand.SelectedIndex != -1)
                // kalder tilstandsstyringen
                BrandSelected();

            if (cmbBrand.SelectedIndex != -1 && cmbCategory.SelectedIndex != -1)
            {
                _controller.PopulateGenericItemCollection((ICategory)cmbCategory.SelectedItem, (IBrand)cmbBrand.SelectedItem);

                List<IGenericItem> genericItems = _controller.GetGenericItems();

                cmbGenericItem.Items.Clear();
                cmbItem.Items.Clear();

                foreach (IGenericItem element in genericItems)
                    cmbGenericItem.Items.Add(element);

                // Kalder tilstandsstyringen
                CategorySelected();
            }
        }

        private void TextChanged(object sender, TextChangedEventArgs e)
        {
            var textBox = sender as TextBox;  //Sender castes til en textbox    
            if (textBox != null)
            {
                //Hvis bruger indtaster et tal eller "," tilføjes det til textboxen
                var newText = textBox.Text.Where(c => Char.IsDigit(c) || (c) == ',')
                                     .Aggregate(String.Empty, (current, c) => current + c);
                textBox.Text = newText;
            }
        }

        private void btnSave_Click(object sender, RoutedEventArgs e)
        {
            int genericItemId = ((IGenericItem)cmbGenericItem.SelectedItem).Id;
            string itemDescription = txtDescription.Text;
            string material = (string)cmbMaterial.SelectedItem;
            decimal discountPrice = decimal.Parse(txtDiscountPrice.Text);
            string displayName = txtDisplayName.Text;

            //itemDescription, materiale, discount price og displayName bliver opdateret for det valgte item
            if (_controller.UpdateItemDescription(genericItemId, itemDescription, material, discountPrice, displayName))
                MessageBox.Show("Generel vare updateret!", "Updateret!", MessageBoxButton.OK, MessageBoxImage.Information);
            else
                MessageBox.Show("Der skete en fejl", "Fejl!", MessageBoxButton.OK, MessageBoxImage.Error);
        }

        private void LoadingWindow(object sender, RoutedEventArgs e)
        {
            // Kalder tilstandsstyringen
            OnLoadingWindow(); 
        }

        private void MaterialSelected(object sender, SelectionChangedEventArgs e)
        {
            if (cmbMaterial.SelectedIndex != -1)
                // Kalder tilstandsstyringen
                MaterialSelected(); 
        }

        private void txtDiscountPrice_GotFocus(object sender, RoutedEventArgs e)
        {
            if (txtDiscountPrice.Text == 0.ToString())
                txtDiscountPrice.Text = "";
        }

        private void txtDiscountPrice_LostFocus(object sender, RoutedEventArgs e)
        {
            if (txtDiscountPrice.Text == "")
                txtDiscountPrice.Text = 0.ToString();
        }

        private void tabGoBack_MouseUp(object sender, MouseButtonEventArgs e)
        {
            _window.Content = new Navigation(_window);
        }

        #endregion

        #region Custom window handlers
        private void Close(object sender, MouseButtonEventArgs e)
        {
            _window.Close();
        }

        private void DragMove(object sender, MouseButtonEventArgs e)
        {
            _window.DragMove();
        }

        private void Minimize(object sender, MouseButtonEventArgs e)
        {
            _window.WindowState = WindowState.Minimized;
        }

        private void Normal(object sender, MouseButtonEventArgs e)
        {
            if (_window.windowState)
            {
                _window.WindowState = WindowState.Maximized;
                _window.windowState = false;
            }
            else
            {
                _window.WindowState = WindowState.Normal;
                _window.windowState = true;
            }
        }
        #endregion
    }
}
